package timing.ukulele.third.service.weixin;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import me.chanjar.weixin.common.error.WxErrorException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import timing.ukulele.third.mapper.wexin.WxMenuMapper;
import timing.ukulele.third.persistent.weixin.WxMenu;
import timing.ukulele.third.persistent.weixin.WxMenuRule;
import timing.ukulele.third.config.mp.WxMpConfiguration;
import timing.ukulele.third.constant.Constant;
import timing.ukulele.third.constant.WxConstant;
import timing.ukulele.third.model.weixin.Menu;
import timing.ukulele.third.model.weixin.MenuButton;
import timing.ukulele.third.model.weixin.MenuRule;
import timing.ukulele.third.persistent.weixin.WxApp;
import timing.ukulele.third.service.common.BaseOperatorService;
import java.util.ArrayList;
import java.util.List;

/**
 * 自定义菜单
 */
@Service
@AllArgsConstructor
public class WxMenuService extends BaseOperatorService<WxMenuMapper, WxMenu> {

    private final WxAppService wxAppService;

    private final WxMenuRuleService wxMenuRuleService;

    /***
     * 获取WxApp下的菜单树结构
     * @param appId
     * @return
     */
    public Menu getWxMenu(String appId, String menuRuleId) {
        Menu menu = new Menu();
        // 查询菜单组
        WxMenuRule wxMenuRule = wxMenuRuleService.getById(menuRuleId);
        if(wxMenuRule == null){
            return null;
        }
        MenuRule menuRule = new MenuRule();
        BeanUtil.copyProperties(wxMenuRule, menuRule);
        menuRule.setTag_id(wxMenuRule.getTagId());
        menuRule.setClient_platform_type(wxMenuRule.getClientPlatformType());
        menu.setMatchrule(menuRule);
        // 查出一级菜单
        List<WxMenu> listWxMenu = baseMapper.selectList(Wrappers
                .<WxMenu>query().lambda()
                .eq(WxMenu::getAppId, appId)
                .eq(WxMenu::getParentId, Constant.PARENT_ID)
                .eq(WxMenu::getMenuRuleId, menuRuleId)
                .orderByAsc(WxMenu::getSort));
        List<MenuButton> listMenuButton = new ArrayList<>();
        MenuButton menuButton;
        List<MenuButton> subButtons;
        MenuButton subButton;
        if(listWxMenu!=null&&listWxMenu.size()>0){
            for(WxMenu wxMenu : listWxMenu){
                menuButton = new MenuButton();
                menuButton.setName(wxMenu.getName());
                String type = wxMenu.getType();
                // 无二级菜单（因为一级菜单如果有二级菜单，那么type为空）
                if(StringUtils.isNotBlank(type)){
                    menuButton.setType(type);
                    setButtonValue(menuButton,wxMenu);
                // 有二级菜单
                }else{
                    // 查出二级菜单
                    List<WxMenu> listWxMenu1 = baseMapper.selectList(Wrappers
                            .<WxMenu>query().lambda()
                            .eq(WxMenu::getAppId, appId)
                            .eq(WxMenu::getParentId, wxMenu.getId())
                            .eq(WxMenu::getMenuRuleId, menuRuleId)
                            .orderByAsc(WxMenu::getSort));
                    subButtons = new ArrayList<>();
                    for(WxMenu wxMenu1 : listWxMenu1){
                        subButton = new MenuButton();
                        String type1 = wxMenu1.getType();
                        subButton.setName(wxMenu1.getName());
                        subButton.setType(type1);
                        setButtonValue(subButton,wxMenu1);
                        subButtons.add(subButton);
                    }
                    menuButton.setSub_button(subButtons);
                }
                listMenuButton.add(menuButton);
            }
        }
        menu.setButton(listMenuButton);
        return menu;
    }

    void setButtonValue(MenuButton menuButton, WxMenu wxMenu) {
        menuButton.setId(wxMenu.getId());
        menuButton.setKey(wxMenu.getId().toString());
        menuButton.setUrl(wxMenu.getUrl());
        menuButton.setContent(JSON.parseObject(wxMenu.getContent()));
        menuButton.setRepContent(wxMenu.getRepContent());
        menuButton.setMedia_id(wxMenu.getRepMediaId());
        menuButton.setRepType(wxMenu.getRepType());
        menuButton.setRepName(wxMenu.getRepName());
        menuButton.setAppid(wxMenu.getMaAppId());
        menuButton.setPagepath(wxMenu.getMaPagePath());
        menuButton.setUrl(wxMenu.getUrl());
        menuButton.setRepUrl(wxMenu.getRepUrl());
        menuButton.setRepHqUrl(wxMenu.getRepHqUrl());
        menuButton.setRepDesc(wxMenu.getRepDesc());
        menuButton.setRepThumbMediaId(wxMenu.getRepThumbMediaId());
        menuButton.setRepThumbUrl(wxMenu.getRepThumbUrl());
    }

    /**
     * 保存并发布菜单
     * @param
     */
    @Transactional(rollbackFor = Exception.class)
    public WxMenuRule saveAndRelease(Menu menu) throws WxErrorException {

        String appId = menu.getAppId();
        MenuRule menuRule = menu.getMatchrule();
        if(menuRule != null){
            WxMenuRule wxMenuRule = new WxMenuRule();
            BeanUtil.copyProperties(menuRule, wxMenuRule);
            wxMenuRule.setTagId(menuRule.getTag_id());
            wxMenuRule.setClientPlatformType(menuRule.getClient_platform_type());
            // 保存或修改菜单分组
            wxMenuRule.setAppId(appId);
            wxMenuRuleService.saveOrUpdate(wxMenuRule);
            List<MenuButton> buttons = menu.getButton();
            if(ObjectUtil.isNotNull(menuRule.getId())){
                // 先删除菜单
                baseMapper.delete(Wrappers
                        .<WxMenu>query().lambda()
                        .eq(WxMenu::getAppId, appId)
                        .eq(WxMenu::getMenuRuleId, wxMenuRule.getId()));
                if(WxConstant.WX_MENU_TYPE_2.equals(wxMenuRule.getMenuType())){
                    // 删除微信已有个性化菜单
                    wxMenuRule = wxMenuRuleService.getById(wxMenuRule.getId());
                    WxMpConfiguration.getMpServiceByAppId(wxMenuRule.getAppId()).getMenuService().menuDelete(wxMenuRule.getMenuId());
                }
            }
            WxApp wxApp = wxAppService.findEntityByAppId(appId);
            WxMenu wxMenu = null;
            WxMenu wxMenu1 = null;
            int sort1 = 1;
            int sort2 = 1;
            // 入库菜单
            for(MenuButton menuButton : buttons) {
                wxMenu = new WxMenu();
                setWxMenuValue(wxMenu,menuButton,wxApp);
                wxMenu.setSort(sort1);
                wxMenu.setParentId(Constant.PARENT_ID);
                wxMenu.setMenuRuleId(wxMenuRule.getId());
                baseMapper.insert(wxMenu);
                menuButton.setKey(wxMenu.getId().toString());
                this.setMpH5Url(menuButton);
                sort1++;
                for(MenuButton menuButton1 : menuButton.getSub_button()){
                    wxMenu1 = new WxMenu();
                    setWxMenuValue(wxMenu1,menuButton1,wxApp);
                    wxMenu1.setSort(sort2);
                    wxMenu1.setParentId(wxMenu.getId());
                    wxMenu1.setMenuRuleId(wxMenuRule.getId());
                    baseMapper.insert(wxMenu1);
                    menuButton1.setKey(wxMenu1.getId().toString());
                    this.setMpH5Url(menuButton1);
                    sort2++;
                }
            }
            // 创建菜单
            if(WxConstant.WX_MENU_TYPE_1.equals(wxMenuRule.getMenuType())){
                menu.setMatchrule(null);
            }
            String menuId = WxMpConfiguration.getMpServiceByAppId(appId).getMenuService().menuCreate(menu.toString());
            // 个性化菜单保存菜单id
            if(WxConstant.WX_MENU_TYPE_2.equals(wxMenuRule.getMenuType())){
                wxMenuRule.setMenuId(menuId);
                wxMenuRuleService.updateById(wxMenuRule);
            }
            return wxMenuRule;
        }
        return null;
    }

    @SneakyThrows
    void setMpH5Url(MenuButton menuButton) {
        // 公众号h5页面
        if(WxConstant.WX_MENU_TYPE_MP_H5.equals(menuButton.getType())){
            menuButton.setUrl(menuButton.getPagepath());
            menuButton.setType(WxConstant.WX_MENU_TYPE_VIEW);
        }
    }

    void setWxMenuValue(WxMenu wxMenu, MenuButton menuButton, WxApp wxApp){
        wxMenu.setId(Long.parseLong(menuButton.getKey()));
        wxMenu.setAppId(wxApp.getAppId());
        wxMenu.setType(menuButton.getType());
        wxMenu.setName(menuButton.getName());
        wxMenu.setUrl(menuButton.getUrl());
        wxMenu.setRepMediaId(menuButton.getMedia_id());
        wxMenu.setRepType(menuButton.getRepType());
        wxMenu.setRepName(menuButton.getRepName());
        wxMenu.setMaAppId(menuButton.getAppid());
        wxMenu.setMaPagePath(menuButton.getPagepath());
        wxMenu.setRepContent(menuButton.getRepContent());
        wxMenu.setContent(JSON.toJSONString(menuButton.getContent()));
        wxMenu.setRepUrl(menuButton.getRepUrl());
        wxMenu.setRepHqUrl(menuButton.getRepHqUrl());
        wxMenu.setRepDesc(menuButton.getRepDesc());
        wxMenu.setRepThumbMediaId(menuButton.getRepThumbMediaId());
        wxMenu.setRepThumbUrl(menuButton.getRepThumbUrl());
        menuButton.setRepUrl(null);
        menuButton.setRepDesc(null);
        menuButton.setRepHqUrl(null);
        menuButton.setContent(null);
        menuButton.setRepContent(null);
        menuButton.setRepType(null);
        menuButton.setRepName(null);
        menuButton.setRepThumbMediaId(null);
        menuButton.setRepThumbUrl(null);
    }

    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteWxMenu(String ruleId) throws WxErrorException {
        WxMenuRule wxMenuRule = wxMenuRuleService.getById(ruleId);
        // 删除普通菜单，要删除所有个性化菜单
        if(WxConstant.WX_MENU_TYPE_1.equals(wxMenuRule.getMenuType())){
            // 数据库删除
            wxMenuRuleService.remove(Wrappers
                    .<WxMenuRule>query().lambda()
                    .eq(WxMenuRule::getAppId, wxMenuRule.getAppId()));
            baseMapper.delete(Wrappers
                    .<WxMenu>query().lambda()
                    .eq(WxMenu::getAppId, wxMenuRule.getAppId()));
            // 微信删除
            WxMpConfiguration.getMpServiceByAppId(wxMenuRule.getAppId()).getMenuService().menuDelete();
        }else{
            // 数据库删除
            wxMenuRuleService.removeById(wxMenuRule.getId());
            baseMapper.delete(Wrappers
                    .<WxMenu>query().lambda()
                    .eq(WxMenu::getAppId, wxMenuRule.getAppId())
                    .eq(WxMenu::getMenuRuleId,wxMenuRule.getId()));
            // 微信删除
            WxMpConfiguration.getMpServiceByAppId(wxMenuRule.getAppId()).getMenuService().menuDelete(wxMenuRule.getMenuId());
        }

        return Boolean.TRUE;
    }
}
